package com.xmm.model;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.UnsupportedAudioFileException;

import org.tritonus.share.sampled.file.TAudioFileFormat;

import com.xmm.constants.CONSTANTS;




public class Track implements Music {
	private String mCodeId = "Track" + 
			String.valueOf(System.currentTimeMillis()) +
			String.valueOf(Math.random());
			
	private Map<String, Object> mProps = null;
	
	private List<Artist> mGuestArtists = new ArrayList<Artist>();
	private int mPlayCount 	  = 0;
	
	public Track() {}
	
	public Track(String path) {
		init(new File(path));
	}
	
	public Track(File file) {
		init(file);
	}
	
	public Track(Map<String, Object> map) {
		if(map == null) {
			return;
		}
		mProps = map;
	}
	
	private void init(File file) {
		if(file == null || file.isFile() == false) return;
		long sized = file.length();
		try {
			AudioFileFormat aff = AudioSystem.getAudioFileFormat(file);
			if(aff instanceof TAudioFileFormat) {
				Map<String, Object> props = aff.properties();
				mProps = new HashMap<String, Object>();
				mProps.put(CONSTANTS.TRACK_SIZED_NAME, sized);
				mProps.put(CONSTANTS.TRACK_TITLE_NAME, props.get(CONSTANTS.TRACK_TITLE_NAME));
				mProps.put(CONSTANTS.TRACK_ARTIST_NAME, 
						new Artist((String)props.get(CONSTANTS.TRACK_ARTIST_NAME), null));
				RandomAccessFile raf = new RandomAccessFile(file, "r");
				byte[] data = new byte[(int)sized];
				raf.read(data);
				mProps.put(CONSTANTS.TRACK_DATA_NAME,
						data);
				mProps.put(CONSTANTS.TRACK_LENGTH_NAME,
						(Long)(props.get(CONSTANTS.TRACK_LENGTH_NAME)) / 1000000);
				mProps.put(CONSTANTS.TRACK_ABLUM_NAME, props.get(CONSTANTS.TRACK_ABLUM_NAME));
				mProps.put(CONSTANTS.TRACK_DATE_NAME, props.get(CONSTANTS.TRACK_DATE_NAME));
				mProps.put(CONSTANTS.TRACK_COMMENT_NAME, props.get(CONSTANTS.TRACK_COMMENT_NAME));
				mProps.put(CONSTANTS.TRACK_RATING_NAME, 0.0);
				mProps.put(CONSTANTS.TRACK_LOCATION_NAME, props.get("mp3.copyright"));
			}
		} catch (UnsupportedAudioFileException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void setTitle(String title) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_TITLE_NAME, title);
	}
	public String getTitle() {
		Object object = mProps.get(CONSTANTS.TRACK_TITLE_NAME);
		if(object == null) {
			return null;
		}
		return (String)object;
	}
	
	public void setArtist(Artist artist) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_ARTIST_NAME, artist);
	}
	public Artist getArtist() {
		Object object = mProps.get(CONSTANTS.TRACK_ARTIST_NAME);
		if(object == null) {
			return null;
		}
		return (Artist)object;
	}
	
	public void setData(byte[] data) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_DATA_NAME, data);
	}
	public byte[] getData() {
		Object object = mProps.get(CONSTANTS.TRACK_DATA_NAME);
		if(object == null) {
			return null;
		}
		return (byte[])object;
	}

	public void setLength(long length) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_LENGTH_NAME, length);
	}
	public long getLength() {
		Object object = mProps.get(CONSTANTS.TRACK_LENGTH_NAME);
		if(object == null) {
			return 0;
		}
		return (Long)object;
	}
	
	public void setAveRating(double rating) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_RATING_NAME, rating);
	}
	public double getAveRating() {
		Object object = mProps.get(CONSTANTS.TRACK_RATING_NAME);
		if(object == null) {
			return 0.0;
		}
		return (Double)object;
	}
	
	public void setLocation(String location) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_LOCATION_NAME, location);
	}
	public String getLocation() {
		Object object = mProps.get(CONSTANTS.TRACK_LOCATION_NAME);
		if(object == null) {
			return null;
		}
		return (String)object;
	}
	
	public void setSize(long sized) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_SIZED_NAME, sized);
	}
	public long getSize() {
		Object object = mProps.get(CONSTANTS.TRACK_SIZED_NAME);
		if(object == null) {
			return 0;
		}
		return (Long)object;
	}
	
	public void setAblum(String ablum) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_ABLUM_NAME, ablum);
	}
	public String getAblum() {
		Object object = mProps.get(CONSTANTS.TRACK_ABLUM_NAME);
		if(object == null) {
			return null;
		}
		return (String)object;
	}
	
	public void setDate(String date) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_DATE_NAME, date);

	}
	public String getDate() {
		Object object = mProps.get(CONSTANTS.TRACK_DATE_NAME);
		if(object == null) {
			return null;
		}
		return (String)object;
	}
	
	public void setComment(String comment) {
		if(mProps == null) {
			mProps = new HashMap<String, Object>();
		}
		mProps.put(CONSTANTS.TRACK_COMMENT_NAME, comment);
	}
	public String getComment() {
		Object object = mProps.get(CONSTANTS.TRACK_COMMENT_NAME);
		if(object == null) {
			return null;
		}
		return (String)object;
	}
	
	public void addGustArtist(Artist artist) {
		if(artist == null) {
			return;
		}
		mGuestArtists.add(artist);
	}
	
	public List<String> getAllIndividuals() {
		List<String> tmp = new ArrayList<String>();
		Artist mArtist = getArtist();
		if(mArtist != null) {
			tmp.addAll(mArtist.toList());
		}
		for(Artist artist : mGuestArtists) {
			if(artist != null) {
				tmp.addAll(artist.toList());
			}
		}
		return tmp;
	}
	
	public Map<String, Object> getAllProps() {
		return mProps;
	}
	
	public int incrPlayCount() {
		return ++mPlayCount;
	}
	public int getPlayCount() {
		return mPlayCount;
	}
	
	@Override
	public String getCodeId() {
		return mCodeId;
	}
	
	@Override
	public Music removeFrom(String CodeId) {
		return null;
	}
	
	@Override
	public int getClidrenCount() {
		return 0;
	}
}
